<?php
    /**
     * Created by PhpStorm.
     * User: jackhhy
     * Date: 2019/7/4-9:02
     * Link: https://gitee.com/luckygyl/LuckyAdmin
     * FileName: Databackup.php
     * Keys: ctrl+alt+L/ctrl+s(代码格式化) ctrl+J(代码提示) ctrl+R(替换)ALT+INSERT(生成代码(如GET,SET方法,构造函数等) , 光标在类中才生效)
     * CTRL+ALT+O (优化导入的类和包 需要配置) SHIFT+F2(高亮错误或警告快速定位错误)
     * CTRL+SHIFT+Z(代码向前) CTRL+SHIFT+/ (块状注释) ctrl+shift+enter(智能完善代码 如if())
     *
     **************************************************************
     *                                                            *
     *   .=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-.       *
     *    |                     ______                     |      *
     *    |                  .-"      "-.                  |      *
     *    |                 /            \                 |      *
     *    |     _          |              |          _     |      *
     *    |    ( \         |,  .-.  .-.  ,|         / )    |      *
     *    |     > "=._     | )(__/  \__)( |     _.=" <     |      *
     *    |    (_/"=._"=._ |/     /\     \| _.="_.="\_)    |      *
     *    |           "=._"(_     ^^     _)"_.="           |      *
     *    |               "=\__|IIIIII|__/="               |      *
     *    |              _.="| \IIIIII/ |"=._              |      *
     *    |    _     _.="_.="\          /"=._"=._     _    |      *
     *    |   ( \_.="_.="     `--------`     "=._"=._/ )   |      *
     *    |    > _.="                            "=._ <    |      *
     *    |   (_/                                    \_)   |      *
     *    |                                                |      *
     *    '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-='      *
     *                                                            *
     *                    JUST FIND YOUR BUG !                    *
     **************************************************************
     */

    namespace app\admin\controller;

    use service\UtilService;
    use think\Controller;
    use think\Db;
    use think\Request;
    use think\Session;
    use tp5er\Backup;

    class Databackup extends SystemBase
    {


        protected function _initialize()
        {
            parent::_initialize(); // TODO: Change the autogenerated stub
        }


        /**
         * @return mixed
         * @throws \Exception
         * @author: Jackhhy <jackhhy520@qq.com>
         * @name: index
         * @describe:数据备份
         */
        public function index()
        {
            $db = new Backup();
            // dump($db->dataList());
            return $this->fetch('index', ['list' => $db->dataList()]);
        }



        /**
         * @return mixed
         * @throws \Exception
         * @author: Jackhhy <jackhhy520@qq.com>
         * @name: importlist
         * @describe:备份文件列表
         */
        public function importlist()
        {
            $db = new Backup();
            return $this->fetch('importlist', ['list' => $db->fileList()]);
        }


        /**
         * @return mixed
         * @throws \Exception
         * @author: Jackhhy <jackhhy520@qq.com>
         * @name: show_table
         * @describe:查看表属性
         */
        public function show_table()
        {
            $db    = new Backup();
            $table = $this->request->param("table");

            return $this->fetch('show_table', ['list' => $db->dataList($table)]);
        }

        /**
         * @param int $time
         * @param null $part
         * @param null $start
         * @throws \Exception
         * @author: Jackhhy <jackhhy520@qq.com>
         * @name: import
         * @describe:导入备份
         */
        public function import($time = 0, $part = null, $start = null)
        {
            $db = new Backup();
            if(is_numeric($time) && is_null($part) && is_null($start)) {
                $list = $db->getFile('timeverif', $time);
                if(is_array($list)) {
                    session::set('backup_list', $list);
                    $this->success('初始化完成！', '', ['part' => 1, 'start' => 0]);
                }
                else {
                    $this->error('备份文件可能已经损坏，请检查！');
                }
            }
            else if(is_numeric($part) && is_numeric($start)) {

                $list = session::get('backup_list');

                $start = $db->setFile($list)->import($start);

                if(false===$start) {
                    $this->error('还原数据出错！');
                }
                else if(0===$start) {
                    if(isset($list[++$part])) {
                        $data = ['part' => $part, 'start' => 0];
                        $this->success("正在还原...#{$part}", '', $data);
                    }
                    else {
                        session::delete('backup_list');

                        $this->success('还原完成！');
                    }
                }
                else {
                    $data = ['part' => $part, 'start' => $start[0]];
                    if($start[1]) {
                        $rate = floor(100*($start[0]/$start[1]));
                        $this->success("正在还原...#{$part} ({$rate}%)", '', $data);
                    }
                    else {
                        $data['gz'] = 1;
                        $this->success("正在还原...#{$part}", '', $data);
                    }
                    $this->success("正在还原...#{$part}", '');

                }


            }
            else {
                $this->error('参数错误！');
            }


        }


        /**
         * @param int $time
         * @throws \Exception
         * @author: Jackhhy <jackhhy520@qq.com>
         * @name: del
         * @describe:删除备份文件
         */
        public function del($time = 0)
        {
            $db = new Backup();
            if($db->delFile($time)) {


                $this->AddLogs('删除数据库备份文件');

                $this->success("备份文件删除成功！", 'admin/databackup/importlist');
            }
            else {
                $this->error("备份文件删除失败，请检查权限！");
            }
        }


        /**
         * @throws \Exception
         * @author: Jackhhy <jackhhy520@qq.com>
         * @name: export
         * @describe:备份文件
         */
        public function export()
        {
            $db = new Backup();
            if(Request::instance()->isPost()) {
                $input = input('post.');

                $fileinfo = $db->getFile();
                //检查是否有正在执行的任务
                $lock = "{$fileinfo['filepath']}backup.lock";
                if(is_file($lock)) {
                    $this->error('检测到有一个备份任务正在执行，请稍后再试！');
                }
                else {
                    //创建锁文件
                    file_put_contents($lock, time());
                }
                // 检查备份目录是否可写
                is_writeable($fileinfo['filepath']) || $this->error('备份目录不存在或不可写，请检查后重试！');

                //缓存锁文件
                session::set('lock', $lock);
                //缓存备份文件信息
                session::set('backup_file', $fileinfo['file']);
                //缓存要备份的表
                session::set('backup_tables', $input['tables']);
                //创建备份文件
                if(false!==$db->Backup_Init()) {
                    $ars = ['describe' => '备份数据表', 'type' => 2, 'admin_name' => self::$admin_info['username'], 'browse' => UtilService::getBrowser(), 'model' => self::$mode_name, 'controller' => self::$controller_name, 'action' => self::$action_name];
                    AddLogs($ars); //添加操作日志
                    $this->success('初始化成功！', '', ['tab' => ['id' => 0, 'start' => 0]]);
                }
                else {
                    $this->error('初始化失败，备份文件创建失败！');
                }
            }
            else if(Request::instance()->isGet()) {
                $tables = session::get('backup_tables');
                $file   = session::get('backup_file');

                $id    = input('id');
                $start = input('start');
                $start = $db->setFile($file)->backup($tables[$id], $start);
                if(false===$start) {
                    $this->error('备份出错！');
                }
                else if(0===$start) {
                    if(isset($tables[++$id])) {
                        $tab = ['id' => $id, 'start' => 0];
                        $ars = ['describe' => '备份数据表', 'type' => 2, 'admin_name' => self::$admin_info['username'], 'browse' => UtilService::getBrowser(), 'model' => self::$mode_name, 'controller' => self::$controller_name, 'action' => self::$action_name];
                        AddLogs($ars); //添加操作日志
                        $this->success('备份完成！', '', ['tab' => $tab]);
                    }
                    else { //备份完成，清空缓存
                        unlink(session::get('lock'));
                        Session::delete('backup_tables');
                        Session::delete('backup_file');
                        $this->success('备份完成！');
                    }
                }
            }
            else {
                $this->error('参数错误！');
            }


        }


        /**
         * @param null $tables
         * @throws \Exception
         * @author: Jackhhy <jackhhy520@qq.com>
         * @name: repair
         * @describe:修复表
         */
        public function repair($tables = null)
        {
            $db = new Backup();
            if($db->repair($tables)) {
                 $this->success("数据表修复完成！");
            }
            else {
                 $this->error("数据表修复出错请重试");
            }
        }



        /**
         * @param null $tables
         * @throws \Exception
         * @author: Jackhhy <jackhhy520@qq.com>
         * @name: optimize
         * @describe:优化表
         */
        public function optimize($tables = null)
        {
            $db = new Backup();
            if($db->optimize($tables)) {
                 $this->success("数据表优化完成！");
            }
            else {
                 $this->error("数据表优化出错请重试！");
            }
        }

    }

